<!doctype html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box-wrapper {
            display: flex;
        }

        .column-box {
            flex: 1;
            margin-right: 20px;
        }

        .box-wrapper .column-box:last-child {
            margin-right: 0;
        }

        .box-item {
            margin-bottom: 20px;
            height: 100%;
            background: #4286F5;
            box-sizing: border-box;
            font-size: 40px;
            font-weight: bold;
            color: #ffc107;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .loading,
        .loading:before,
        .loading:after {
            background: #01b909;
            animation: load1 1s infinite ease-in-out;
            width: 1em;
            height: 4em;
            border-radius: 8px;
        }

        .loading:before,
        .loading:after {
            position: absolute;
            top: 0;
            content: '';
        }

        .loading:before {
            left: -1.5em;
        }

        .loading {
            position: fixed;
            bottom: 0;
            left: 50%;
            transform: translateY(-50%);
            margin: 20px auto;
            font-size: 11px;
            animation-delay: 0.16s;
        }

        .loading:after {
            left: 1.5em;
            animation-delay: 0.32s;
        }

        @keyframes load1 {
            0%,
            80%,
            100% {
                box-shadow: 0 0 #01b909;
                height: 3em;
            }
            40% {
                /* 实现上部拉伸 */
                box-shadow: 0 -2em #01b909;
                /* 实现下部拉伸 */
                height: 4em;
            }
        }
    </style>
</head>
<body>
<div class="box-wrapper">
    <div class="column-box"></div>
    <div class="column-box"></div>
    <div class="column-box"></div>
    <div class="column-box"></div>
</div>

<script>
    let counter = 0
    const INITIAL_NUMBER = 40
    const MAX_HEIGHT = 400
    const MIN_HEIGHT = 200
    const columnBoxList = document.querySelectorAll('.column-box')


    function createDiv() {
        const div = document.createElement('div')
        const randomHeight = Math.floor(Math.random() * (MAX_HEIGHT - MIN_HEIGHT + 1) + MIN_HEIGHT)
        div.innerHTML = `${++counter}`
        div.style.height = `${randomHeight}px`
        div.classList.add('box-item')
        return div
    }

    function createFragments(num) {
        const fragments = []

        for (let j = 0; j < 4; j++) {
            fragments.push(document.createDocumentFragment())
        }

        function pushItem(current, arrIndex) {
            current % 4 === arrIndex && fragments[arrIndex].appendChild(createDiv())
        }

        for (let i = 0; i < num; i++) {
            pushItem(i, 0)
            pushItem(i, 1)
            pushItem(i, 2)
            pushItem(i, 3)
        }

        return fragments
    }

    function createLoading() {
        let loading = document.querySelector('.loading')
        if (!loading) {
            loading = document.createElement('div')
            loading.classList.add('loading')
        }
        return loading
    }

    function appendHandler(num) {
        const elements = createFragments(num)
        columnBoxList.forEach((column, i) => {
            column.appendChild(elements[i])
        })
    }

    function init() {
        appendHandler(INITIAL_NUMBER)
    }

    function scrollHandler() {
        const {scrollTop, clientHeight, offsetHeight} = document.documentElement
        const nearBottom = offsetHeight - clientHeight === scrollTop

        if (nearBottom) {
            const loading = createLoading()
            document.body.appendChild(loading)
            setTimeout(() => {
                document.body.removeChild(loading)
                appendHandler(20)
            }, 1000)
        }
    }

    function debounce(callback, delay) {
        let timer = null
        return function () {
            clearTimeout(timer)
            timer = setTimeout(callback, delay)
        }
    }

    window.addEventListener('load', init)
    window.addEventListener('scroll', debounce(scrollHandler, 100))
</script>
</body>
</html>
